'use client';

import { useState, useEffect } from 'react';
import Image from 'next/image';
import { toast } from 'react-hot-toast';
import { useDropzone } from 'react-dropzone';
import type { CreateXLayerTokenParams, XLayerToken } from '@/types/xlayer';
import { useXLayerWallet } from '@/hooks/useXLayerWallet';
import { apiClient } from '../lib/api';

interface CreateXLayerTokenFormProps {
  onTokenCreated: (token: XLayerToken) => void;
}

// X Layer Configuration
const XLAYER_CONFIG = {
  chainId: process.env.NEXT_PUBLIC_XLAYER_CHAIN_ID === '196' ? '0xC4' : '0x7A0', // Hex for 196 (mainnet) or 1952 (testnet)
  chainName: process.env.NEXT_PUBLIC_XLAYER_CHAIN_ID === '196' ? 'X Layer Mainnet' : 'X Layer Testnet',
  nativeCurrency: {
    name: 'OKB',
    symbol: 'OKB',
    decimals: 18,
  },
  rpcUrls: [process.env.NEXT_PUBLIC_XLAYER_RPC_URL!],
  blockExplorerUrls: [process.env.NEXT_PUBLIC_XLAYER_CHAIN_ID === '196' ? 'https://www.oklink.com/xlayer' : 'https://www.oklink.com/x1-test'],
};

export function CreateXLayerTokenForm({ onTokenCreated }: CreateXLayerTokenFormProps) {
  const { address, isConnected, connect, signer } = useXLayerWallet();
  const [isLoading, setIsLoading] = useState(false);
  const [uploadingImage, setUploadingImage] = useState(false);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [errors, setErrors] = useState<Record<string, string>>({});
  
  const [formData, setFormData] = useState<CreateXLayerTokenParams>({
    name: '',
    symbol: '',
    description: '',
    website: '',
    telegram: '',
    twitter: '',
    targetAmount: '50',
    tokenPrice: '0.0001',
    imageFile: undefined
  });

  // Check if X Layer network is already added
  useEffect(() => {
    const checkNetwork = async () => {
      if (window.ethereum) {
        try {
          const chainId = await window.ethereum.request({ method: 'eth_chainId' });
          if (chainId !== XLAYER_CONFIG.chainId) {
            toast(`Please switch to ${XLAYER_CONFIG.chainName}`, { icon: '⚠️' });
          }
        } catch (error) {
          console.error('Check network failed:', error);
        }
      }
    };

    if (isConnected) {
      checkNetwork();
    }
  }, [isConnected]);

  // Add X Layer network to wallet
  const addXLayerNetwork = async () => {
    if (!window.ethereum) {
      toast.error('Wallet not detected');
      return false;
    }

    try {
      await window.ethereum.request({
        method: 'wallet_addEthereumChain',
        params: [XLAYER_CONFIG],
      });
      toast.success(`${XLAYER_CONFIG.chainName} added successfully`);
      return true;
    } catch (error: unknown) {
      console.error('Failed to add network:', error);
      const message = error instanceof Error ? error.message : 'Failed to add network';
      toast.error(message);
      return false;
    }
  };

  // Switch to X Layer network
  const switchToXLayerNetwork = async () => {
    if (!window.ethereum) {
      toast.error('Wallet not detected');
      return false;
    }

    try {
      await window.ethereum.request({
        method: 'wallet_switchEthereumChain',
        params: [{ chainId: XLAYER_CONFIG.chainId }],
      });
      return true;
    } catch (error: unknown) {
      // If network not added, add it first
      if (error && typeof error === 'object' && 'code' in error && error.code === 4902) {
        return await addXLayerNetwork();
      }
      const message = error instanceof Error ? error.message : 'Failed to switch network';
      toast.error(message);
      return false;
    }
  };

  const handleInputChange = (field: keyof CreateXLayerTokenParams, value: string | File) => {
    setFormData(prev => ({ ...prev, [field]: value }));
  };

  // Use useDropzone for image upload handling
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    accept: {
      'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'],
    },
    maxFiles: 1,
    maxSize: 5 * 1024 * 1024, // 5MB
    multiple: false,
    preventDropOnDocument: true,
    onDrop: (acceptedFiles) => {
      console.log('onDrop triggered:', acceptedFiles);
      const file = acceptedFiles[0];
      if (file) {
        console.log('File selected:', file.name, file.size, file.type);
        handleInputChange('imageFile', file);
        
        // Create preview
        const reader = new FileReader();
        reader.onload = () => {
          console.log('FileReader loaded, setting preview');
          setImagePreview(reader.result as string);
        };
        reader.readAsDataURL(file);

        // Clear image error
        setErrors((prev) => ({ ...prev, image: '' }));
        
        // Show success message
        toast.success(`Image selected: ${file.name}`);
      }
    },
    onDropRejected: (rejectedFiles) => {
      console.log('onDropRejected triggered:', rejectedFiles);
      const rejection = rejectedFiles[0];
      if (rejection.errors[0]?.code === 'file-too-large') {
        toast.error('Image file cannot exceed 5MB');
        setErrors((prev) => ({ ...prev, image: 'Image file cannot exceed 5MB' }));
      } else {
        toast.error('Please upload a valid image file');
        setErrors((prev) => ({ ...prev, image: 'Please upload a valid image file' }));
      }
    },
    onDragEnter: () => {
      console.log('onDragEnter triggered');
    },
    onDragOver: () => {
      console.log('onDragOver triggered');
    },
    onDragLeave: () => {
      console.log('onDragLeave triggered');
    },
    onFileDialogCancel: () => {
      console.log('File dialog cancelled');
    },
  });

  // Upload image to backend
  const uploadImage = async (file: File): Promise<string> => {
    setUploadingImage(true);
    try {
      const response = await apiClient.uploadImage(file);

      if (response.success && response.data) {
        return response.data.url;
      } else {
        throw new Error(response.message || "Failed to upload image");
      }
    } catch (error: unknown) {
      console.error("Image upload error:", error);
      const errorMessage =
        (error as { response?: { data?: { message?: string } } })?.response?.data?.message ||
        (error as { message?: string })?.message ||
        "Failed to upload image";
      throw new Error(errorMessage);
    } finally {
      setUploadingImage(false);
    }
  };

  const validateForm = (): string | null => {
    if (!formData.name.trim()) return 'Please enter token name';
    if (!formData.symbol.trim()) return 'Please enter token symbol';
    if (!formData.description.trim()) return 'Please enter token description';
    if (parseFloat(formData.targetAmount) < 0.1) return 'Minimum funding target is 0.1 OKB';
    if (parseFloat(formData.targetAmount) > 100) return 'Maximum funding target is 100 OKB';
    if (parseFloat(formData.tokenPrice) <= 0) return 'Token price must be greater than 0';
    return null;
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    
    if (!isConnected) {
      toast.error('Please connect your wallet first');
      return;
    }

    // Ensure we're on the correct network
    const isOnCorrectNetwork = await switchToXLayerNetwork();
    if (!isOnCorrectNetwork) {
      toast.error('Please switch to X Layer Test Network');
      return;
    }

    const validationError = validateForm();
    if (validationError) {
      toast.error(validationError);
      return;
    }

    setIsLoading(true);
    
    try {
      // Upload image first if exists
      let imageUrl = '';
      if (formData.imageFile) {
        toast.loading('Uploading image...', { id: 'upload' });
        imageUrl = await uploadImage(formData.imageFile);
        toast.success('Image uploaded successfully', { id: 'upload' });
      }

      // Show fee confirmation
      const confirmMessage = `
Estimated Creation Fees:
• Contract Creation Fee: 0.01 OKB
• Gas Fee: ~0.005 OKB
• Total Fee: ~0.015 OKB

Continue with token creation?
      `;
      
      if (!confirm(confirmMessage.trim())) {
        toast.error('Creation cancelled', { id: 'create-tx' });
        return;
      }

      toast.loading('Preparing transaction data...', { id: 'create-tx' });

      // Use prepare-create to get transaction data
      const prepareResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:7172/api'}/xlayer/tokens/prepare-create`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: formData.name,
          symbol: formData.symbol,
          description: formData.description,
          website: formData.website,
          telegram: formData.telegram,
          twitter: formData.twitter,
          imageUrl,
          targetAmount: parseFloat(formData.targetAmount),
          creatorAddress: address
        })
      });

      if (!prepareResponse.ok) {
        const errorData = await prepareResponse.json();
        throw new Error(errorData.message || 'Failed to prepare transaction');
      }

      const responseData = await prepareResponse.json();
      
      // Check response format
      if (!responseData.success || !responseData.transaction) {
        throw new Error('Invalid transaction data format');
      }
      
      toast.loading('Waiting for wallet confirmation...', { id: 'create-tx' });

      // Send transaction to wallet for signing
      if (!signer) {
        throw new Error('Wallet not connected or signer unavailable');
      }

      const txHash = await signer.sendTransaction({
        to: responseData.transaction.to,
        data: responseData.transaction.data,
        value: responseData.transaction.value,
        gasLimit: responseData.transaction.gasLimit,
        gasPrice: responseData.transaction.gasPrice
      });

      toast.loading('Waiting for transaction confirmation...', { id: 'create-tx' });

      // Wait for transaction confirmation
      const receipt = await txHash.wait();
      
      if (!receipt || receipt.status !== 1) {
        throw new Error('Transaction failed');
      }

      toast.loading('Saving token information...', { id: 'create-tx' });

      // Call backend confirm-create endpoint to parse transaction events and save token info
      const confirmResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:7172/api'}/xlayer/tokens/confirm-create`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          transactionHash: receipt.hash,
          creatorAddress: address,
          name: formData.name,
          symbol: formData.symbol,
          description: formData.description,
          website: formData.website,
          telegram: formData.telegram,
          twitter: formData.twitter,
          imageUrl,
          targetAmount: parseFloat(formData.targetAmount),
        })
      });

      if (!confirmResponse.ok) {
        const errorData = await confirmResponse.json();
        throw new Error(errorData.message || 'Failed to save token information');
      }

      const confirmData = await confirmResponse.json();
      
      if (!confirmData.success || !confirmData.token) {
        throw new Error('Failed to save token information');
      }

      toast.success('Token created successfully!', { id: 'create-tx' });

      // Use complete token information returned from backend
      const newToken: XLayerToken = {
        id: confirmData.token.id || receipt.hash,
        launchId: confirmData.token.launch_id || 0,
        tokenAddress: confirmData.token.token_address || '',
        creator: confirmData.token.creator || address || '',
        name: confirmData.token.name,
        symbol: confirmData.token.symbol,
        description: confirmData.token.description,
        website: confirmData.token.website,
        telegram: confirmData.token.telegram,
        twitter: confirmData.token.twitter,
        imageUrl: confirmData.token.image_url || imageUrl,
        targetAmount: confirmData.token.target_amount || formData.targetAmount,
        raisedAmount: confirmData.token.raised_amount || '0',
        tokenPrice: confirmData.token.token_price || formData.tokenPrice,
        createdAt: confirmData.token.created_at ? new Date(confirmData.token.created_at).getTime() : Date.now(),
        deadline: confirmData.token.deadline ? new Date(confirmData.token.deadline).getTime() : Date.now() + 30 * 24 * 60 * 60 * 1000,
        launched: confirmData.token.launched || false,
        cancelled: confirmData.token.cancelled || false,
        currentPrice: confirmData.token.token_price || formData.tokenPrice,
        marketCap: '0',
        holders: 0
      };
      
      onTokenCreated(newToken);
      
      // Reset form
      setFormData({
        name: '',
        symbol: '',
        description: '',
        website: '',
        telegram: '',
        twitter: '',
        targetAmount: '50',
        tokenPrice: '0.0001',
        imageFile: undefined
      });
      setImagePreview(null);
      
    } catch (error: unknown) {
      console.error('Token creation error:', error);
      
      const errorMessage = error instanceof Error ? 
        (error as Error & { reason?: string }).reason || error.message : 
        'An error occurred during creation';
      toast.error(errorMessage, { id: 'create-tx' });
    } finally {
      setIsLoading(false);
    }
  };

  if (!isConnected) {
    return (
      <div className="pixel-card w-full mx-auto p-6 md:p-8">
        <div className="text-center py-12">
          <div className="mb-4">
            <div className="w-16 h-16 mx-auto bg-orange-100 rounded-full flex items-center justify-center">
              <svg className="w-8 h-8 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
              </svg>
            </div>
          </div>
          <h3 className="text-lg font-medium text-gray-300 mb-2 font-pixel">Connect Wallet to Create Token</h3>
          <p className="text-gray-400 mb-6 font-body">You need to connect an X Layer compatible wallet to create tokens</p>
          <button
            onClick={connect}
            className="bg-orange-600 hover:bg-orange-700 text-white px-6 py-3 rounded-lg font-medium transition-colors font-body"
          >
            Connect Wallet
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="pixel-card w-full mx-auto p-6 md:p-8">
      <h2 className="text-2xl md:text-3xl font-bold mb-6 font-pixel text-center">Create XLayer Token</h2>
      
      <form onSubmit={handleSubmit} className="space-y-8 w-full">
        {/* Basic Information */}
        <div className="pixel-card p-5 md:p-6">
          <h3 className="text-lg font-medium font-pixel mb-4">Basic Information</h3>
          
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                Token Name *
              </label>
              <input
                type="text"
                value={formData.name}
                onChange={(e) => handleInputChange('name', e.target.value)}
                placeholder="e.g., My Token"
                className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                required
              />
            </div>
            
            <div>
              <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                Token Symbol *
              </label>
              <input
                type="text"
                value={formData.symbol}
                onChange={(e) => handleInputChange('symbol', e.target.value.toUpperCase())}
                placeholder="e.g., MTK"
                className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                required
              />
            </div>
          </div>
          
          <div className="mt-4">
            <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
              Token Description *
            </label>
            <textarea
              value={formData.description}
              onChange={(e) => handleInputChange('description', e.target.value)}
              placeholder="Describe your token project..."
              rows={3}
              className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
              required
            />
          </div>
        </div>

        {/* Image Upload */}
        <div className="pixel-card p-5 md:p-6">
          <h3 className="text-lg font-medium font-pixel mb-4">Token Icon</h3>
          
          <div
            {...getRootProps()}
            className={`border-2 border-dashed border-gray-600 bg-gray-700 p-8 md:p-10 text-center cursor-pointer transition-colors hover:border-orange-500 ${
              isDragActive
                ? "border-orange-500 bg-gray-600"
                : errors.image
                ? "border-red-500 bg-red-900"
                : ""
            }`}
            onClick={() => console.log('Upload area clicked')}
          >
            <input {...getInputProps()} />
            {imagePreview ? (
              <div className="space-y-4">
                <Image
                  src={imagePreview}
                  alt="Preview"
                  width={96}
                  height={96}
                  className="mx-auto rounded-lg object-cover"
                />
                <p className="text-sm text-gray-400 font-body">
                  Click or drag to replace image
                </p>
              </div>
            ) : (
              <div className="space-y-2">
                <div className="text-gray-400">
                  <svg
                    className="w-12 h-12 mx-auto"
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                  >
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
                    />
                  </svg>
                </div>
                <p className="text-sm text-gray-400 font-body">
                  {isDragActive ? "Drop file here..." : "Click to upload or drag image here"}
                </p>
                <p className="text-xs text-gray-500 font-body">
                  Supports PNG, JPG, GIF, max 5MB
                </p>
              </div>
            )}
          </div>
          {errors.image && (
            <p className="text-red-500 text-sm mt-1">{errors.image}</p>
          )}
        </div>

        {/* Launch Parameters */}
        <div className="pixel-card p-5 md:p-6">
          <h3 className="text-lg font-medium font-pixel mb-4">Launch Parameters</h3>
          
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                Funding Target (OKB) *
              </label>
              <input
                type="number"
                step="0.1"
                min="0.1"
                max="100"
                value={formData.targetAmount}
                onChange={(e) => handleInputChange('targetAmount', e.target.value)}
                className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                required
              />
              <p className="text-sm text-gray-400 mt-1 font-body">Min 0.1 OKB, Max 100 OKB</p>
            </div>
            
            <div>
              <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                Token Price (OKB) *
              </label>
              <input
                type="number"
                step="0.0001"
                min="0.0001"
                value={formData.tokenPrice}
                onChange={(e) => handleInputChange('tokenPrice', e.target.value)}
                className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                required
              />
              <p className="text-sm text-gray-400 mt-1 font-body">Price per token</p>
            </div>
          </div>
          
          <div className="mt-4 p-4 bg-gray-800 rounded-lg border border-orange-200">
            <div className="text-sm font-body">
              <div className="flex justify-between mb-1">
                <span className="text-gray-300">Estimated Supply:</span>
                <span className="font-medium text-white">
                  {formData.targetAmount && formData.tokenPrice 
                    ? Math.floor(parseFloat(formData.targetAmount) / parseFloat(formData.tokenPrice)).toLocaleString()
                    : '0'
                  } {formData.symbol || 'tokens'}
                </span>
              </div>
              <div className="flex justify-between mb-1">
                <span className="text-gray-300">Launch Duration:</span>
                <span className="font-medium text-white">7 days</span>
              </div>
              <div className="flex justify-between">
                <span className="text-gray-300">Creation Fee:</span>
                <span className="font-medium text-white">0.02 OKB</span>
              </div>
              <div className="flex justify-between">
                <span className="text-gray-400 text-xs">  - Contract Fee:</span>
                <span className="font-medium text-gray-300 text-xs">0.01 OKB</span>
              </div>
              <div className="flex justify-between">
                <span className="text-gray-400 text-xs">  - Gas Fee:</span>
                <span className="font-medium text-gray-300 text-xs">0.01 OKB</span>
              </div>
            </div>
          </div>
        </div>

        {/* Social Links */}
        <div className="pixel-card p-5 md:p-6">
          <h3 className="text-lg font-medium font-pixel mb-4">Social Links (Optional)</h3>
          
          <div className="space-y-4">
            <div>
              <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                Website
              </label>
              <input
                type="url"
                value={formData.website}
                onChange={(e) => handleInputChange('website', e.target.value)}
                placeholder="https://example.com"
                className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
              />
            </div>
            
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div>
                <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                  Telegram
                </label>
                <input
                  type="text"
                  value={formData.telegram}
                  onChange={(e) => handleInputChange('telegram', e.target.value)}
                  placeholder="@username"
                  className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                />
              </div>
              
              <div>
                <label className="block text-base md:text-lg font-semibold text-gray-300 mb-3 font-body text-center">
                  Twitter
                </label>
                <input
                  type="text"
                  value={formData.twitter}
                  onChange={(e) => handleInputChange('twitter', e.target.value)}
                  placeholder="@username"
                  className="w-full px-3 py-2 border border-orange-200 rounded-lg focus:ring-2 focus:ring-orange-500 focus:border-transparent font-body"
                />
              </div>
            </div>
          </div>
        </div>

        {/* Submit Button */}
        <div className="text-center">
          <button
            type="submit"
            disabled={isLoading || uploadingImage}
            className={`w-full md:w-auto px-8 py-3 rounded-lg font-medium text-white transition-colors font-body ${
              isLoading || uploadingImage
                ? 'bg-gray-400 cursor-not-allowed'
                : 'bg-orange-600 hover:bg-orange-700'
            }`}
          >
            {uploadingImage ? (
              <span className="flex items-center justify-center">
                <svg className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                  <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
                Uploading image...
              </span>
            ) : isLoading ? (
              <span className="flex items-center justify-center">
                <svg className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                  <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
                Creating...
              </span>
            ) : (
              'Create Token Launch (0.02 OKB)'
            )}
          </button>
          
          <p className="text-sm text-gray-400 mt-2 font-body">
            Total deduction: 0.02 OKB (0.01 contract fee + 0.01 gas fee)
          </p>
        </div>
      </form>
    </div>
  );
}